* cap version and next pointer all being 0.
*/
if ( (header == 0) || (header == -1) )
- {
- dprintk(XENLOG_INFO VTDPREFIX,
- "next cap:%x:%x.%x: no extended config\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
return 0;
- }
while ( ttl-- > 0 ) {
if ( PCI_EXT_CAP_ID(header) == cap )
dest = set_desc_affinity(desc, mask);
if (dest == BAD_APICID){
- gdprintk(XENLOG_ERR, "Set iommu interrupt affinity error!\n");
+ dprintk(XENLOG_ERR, "Set iommu interrupt affinity error!\n");
return;
}
irq = create_irq();
if ( irq <= 0 )
{
- gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no irqs\n");
+ dprintk(XENLOG_ERR, "IOMMU: no irqs\n");
return 0;
}
}
}
- gdprintk(XENLOG_INFO VTDPREFIX,
- "VT-d irq bind: m_irq = %x device = %x intx = %x\n",
- machine_gsi, device, intx);
spin_unlock(&d->event_lock);
+
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ "d%d: bind: m_gsi=%u g_gsi=%u device=%u intx=%u\n",
+ d->domain_id, machine_gsi, guest_gsi, device, intx);
}
return 0;
}
guest_gsi = hvm_pci_intx_gsi(device, intx);
link = hvm_pci_intx_link(device, intx);
- gdprintk(XENLOG_INFO,
- "pt_irq_destroy_bind_vtd: machine_gsi=%d "
- "guest_gsi=%d, device=%d, intx=%d.\n",
- machine_gsi, guest_gsi, device, intx);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ "d%d: unbind: m_gsi=%u g_gsi=%u device=%u intx=%u\n",
+ d->domain_id, machine_gsi, guest_gsi, device, intx);
+
spin_lock(&d->event_lock);
hvm_irq_dpci = domain_get_irq_dpci(d);
}
}
spin_unlock(&d->event_lock);
- gdprintk(XENLOG_INFO,
- "XEN_DOMCTL_irq_unmapping: m_irq = 0x%x device = 0x%x intx = 0x%x\n",
- machine_gsi, device, intx);
+
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ "d%d unmap: m_irq=%u device=%u intx=%u\n",
+ d->domain_id, machine_gsi, device, intx);
return 0;
}
* no-intremap Disable VT-d Interrupt Remapping
*/
custom_param("iommu", parse_iommu_param);
-int iommu_enabled = 1;
-int iommu_pv_enabled;
-int force_iommu;
-int iommu_workaround_bios_bug;
-int iommu_passthrough;
-int iommu_snoop = 1;
-int iommu_qinval = 1;
-int iommu_intremap = 1;
-int amd_iommu_debug;
-int amd_iommu_perdev_intremap;
+bool_t __read_mostly iommu_enabled = 1;
+bool_t __read_mostly iommu_pv_enabled;
+bool_t __read_mostly force_iommu;
+bool_t __read_mostly iommu_verbose;
+bool_t __read_mostly iommu_workaround_bios_bug;
+bool_t __read_mostly iommu_passthrough;
+bool_t __read_mostly iommu_snoop = 1;
+bool_t __read_mostly iommu_qinval = 1;
+bool_t __read_mostly iommu_intremap = 1;
+bool_t __read_mostly amd_iommu_debug;
+bool_t __read_mostly amd_iommu_perdev_intremap;
static void __init parse_iommu_param(char *s)
{
iommu_workaround_bios_bug = 1;
else if ( !strcmp(s, "passthrough") )
iommu_passthrough = 1;
+ else if ( !strcmp(s, "verbose") )
+ iommu_verbose = 1;
else if ( !strcmp(s, "no-snoop") )
iommu_snoop = 0;
else if ( !strcmp(s, "no-qinval") )
if ( pdev->domain != d )
{
- gdprintk(XENLOG_ERR VTDPREFIX,
- "IOMMU: deassign a device not owned\n");
+ dprintk(XENLOG_ERR VTDPREFIX,
+ "d%d: deassign a device not owned\n", d->domain_id);
return -EINVAL;
}
ret = hd->platform_ops->reassign_device(d, dom0, bus, devfn);
if ( ret )
{
- gdprintk(XENLOG_ERR VTDPREFIX,
- "Deassign device (%x:%x.%x) failed!\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ dprintk(XENLOG_ERR VTDPREFIX,
+ "d%d: Deassign device (%x:%x.%x) failed!\n",
+ d->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
return ret;
}
bus, path->dev, path->fn, PCI_SECONDARY_BUS);
sub_bus = pci_conf_read8(
bus, path->dev, path->fn, PCI_SUBORDINATE_BUS);
- dprintk(XENLOG_INFO VTDPREFIX,
- " bridge: %x:%x.%x start = %x sec = %x sub = %x\n",
- bus, path->dev, path->fn,
- acpi_scope->start_bus, sec_bus, sub_bus);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ " bridge: %x:%x.%x start = %x sec = %x sub = %x\n",
+ bus, path->dev, path->fn,
+ acpi_scope->start_bus, sec_bus, sub_bus);
dmar_scope_add_buses(scope, sec_bus, sub_bus);
break;
case ACPI_DEV_MSI_HPET:
- dprintk(XENLOG_INFO VTDPREFIX, " MSI HPET: %x:%x.%x\n",
- bus, path->dev, path->fn);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, " MSI HPET: %x:%x.%x\n",
+ bus, path->dev, path->fn);
break;
case ACPI_DEV_ENDPOINT:
- dprintk(XENLOG_INFO VTDPREFIX, " endpoint: %x:%x.%x\n",
- bus, path->dev, path->fn);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, " endpoint: %x:%x.%x\n",
+ bus, path->dev, path->fn);
break;
case ACPI_DEV_IOAPIC:
- dprintk(XENLOG_INFO VTDPREFIX, " IOAPIC: %x:%x.%x\n",
- bus, path->dev, path->fn);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, " IOAPIC: %x:%x.%x\n",
+ bus, path->dev, path->fn);
if ( type == DMAR_TYPE )
{
dmaru->address = drhd->address;
dmaru->include_all = drhd->flags & 1; /* BIT0: INCLUDE_ALL */
INIT_LIST_HEAD(&dmaru->ioapic_list);
- dprintk(XENLOG_INFO VTDPREFIX, " dmaru->address = %"PRIx64"\n",
- dmaru->address);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, " dmaru->address = %"PRIx64"\n",
+ dmaru->address);
addr = map_to_nocache_virt(0, drhd->address);
dmaru->ecap = dmar_readq(addr, DMAR_ECAP_REG);
if ( dmaru->include_all )
{
- dprintk(XENLOG_INFO VTDPREFIX, " flags: INCLUDE_ALL\n");
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, " flags: INCLUDE_ALL\n");
/* Only allow one INCLUDE_ALL */
if ( include_all )
{
}
else
{
- dprintk(XENLOG_INFO VTDPREFIX,
- " RMRR region: base_addr %"PRIx64" end_address %"PRIx64"\n",
- rmrru->base_address, rmrru->end_address);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ " RMRR region: base_addr %"PRIx64
+ " end_address %"PRIx64"\n",
+ rmrru->base_address, rmrru->end_address);
acpi_register_rmrr_unit(rmrru);
}
}
memset(atsru, 0, sizeof(struct acpi_atsr_unit));
atsru->all_ports = atsr->flags & 1; /* BIT0: ALL_PORTS */
- dprintk(XENLOG_INFO VTDPREFIX,
- " atsru->all_ports: %x\n", atsru->all_ports);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ " atsru->all_ports: %x\n", atsru->all_ports);
if ( !atsru->all_ports )
{
dev_scope_start = (void *)(atsr + 1);
}
else
{
- dprintk(XENLOG_INFO VTDPREFIX, " flags: ALL_PORTS\n");
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, " flags: ALL_PORTS\n");
/* Only allow one ALL_PORTS */
if ( all_ports )
{
rhsau->address = rhsa->address;
rhsau->proximity_domain = rhsa->proximity_domain;
list_add_tail(&rhsau->list, &acpi_rhsa_units);
- dprintk(XENLOG_INFO VTDPREFIX,
- " rhsau->address: %"PRIx64" rhsau->proximity_domain: %"PRIx32"\n",
- rhsau->address, rhsau->proximity_domain);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ " rhsau->address: %"PRIx64
+ " rhsau->proximity_domain: %"PRIx32"\n",
+ rhsau->address, rhsau->proximity_domain);
return ret;
}
}
dmar_host_address_width = dmar->width + 1;
- dprintk(XENLOG_INFO VTDPREFIX, "Host address width %d\n",
- dmar_host_address_width);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "Host address width %d\n",
+ dmar_host_address_width);
entry_header = (struct acpi_dmar_entry_header *)(dmar + 1);
while ( ((unsigned long)entry_header) <
switch ( entry_header->type )
{
case ACPI_DMAR_DRHD:
- dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_DRHD:\n");
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "found ACPI_DMAR_DRHD:\n");
ret = acpi_parse_one_drhd(entry_header);
break;
case ACPI_DMAR_RMRR:
- dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_RMRR:\n");
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "found ACPI_DMAR_RMRR:\n");
ret = acpi_parse_one_rmrr(entry_header);
break;
case ACPI_DMAR_ATSR:
- dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_ATSR:\n");
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "found ACPI_DMAR_ATSR:\n");
ret = acpi_parse_one_atsr(entry_header);
break;
case ACPI_DMAR_RHSA:
- dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_RHSA:\n");
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "found ACPI_DMAR_RHSA:\n");
ret = acpi_parse_one_rhsa(entry_header);
break;
default:
- dprintk(XENLOG_WARNING VTDPREFIX, "Unknown DMAR structure type\n");
+ dprintk(XENLOG_WARNING VTDPREFIX,
+ "Unknown DMAR structure type %x\n",
+ entry_header->type);
ret = -EINVAL;
break;
}
break;
default:
- gdprintk(XENLOG_WARNING VTDPREFIX,
- "set_msi_source_id: unknown type : bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ dprintk(XENLOG_WARNING VTDPREFIX, "d%d: unknown(%u): bdf = %x:%x.%x\n",
+ pdev->domain->domain_id, type,
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
break;
}
}
i = find_next_bit(iommu->domid_bitmap, nr_dom, i+1);
}
- gdprintk(XENLOG_ERR VTDPREFIX,
- "Cannot get valid iommu domid: domid=%d iommu->index=%d\n",
- d->domain_id, iommu->index);
+ dprintk(XENLOG_ERR VTDPREFIX,
+ "Cannot get valid iommu domid: domid=%d iommu->index=%d\n",
+ d->domain_id, iommu->index);
return -1;
}
i = find_first_zero_bit(iommu->domid_bitmap, nr_dom);
if ( i >= nr_dom )
{
- gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no free domain ids\n");
+ dprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no free domain ids\n");
return -EFAULT;
}
iommu->domid_map[i] = d->domain_id;
u32 sts;
unsigned long flags;
- dprintk(XENLOG_INFO VTDPREFIX,
- "iommu_enable_translation: iommu->reg = %p\n", iommu->reg);
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX,
+ "iommu_enable_translation: iommu->reg = %p\n", iommu->reg);
spin_lock_irqsave(&iommu->register_lock, flags);
sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
dmar_writel(iommu->reg, DMAR_GCMD_REG, sts | DMA_GCMD_TE);
drhd->iommu = iommu;
- dprintk(XENLOG_DEBUG VTDPREFIX,
- "drhd->address = %"PRIx64" iommu->reg = %p\n",
- drhd->address, iommu->reg);
- dprintk(XENLOG_DEBUG VTDPREFIX,
- "cap = %"PRIx64" ecap = %"PRIx64"\n", iommu->cap, iommu->ecap);
+ if ( iommu_verbose )
+ {
+ dprintk(VTDPREFIX,
+ "drhd->address = %"PRIx64" iommu->reg = %p\n",
+ drhd->address, iommu->reg);
+ dprintk(VTDPREFIX,
+ "cap = %"PRIx64" ecap = %"PRIx64"\n", iommu->cap, iommu->ecap);
+ }
if ( cap_fault_reg_offset(iommu->cap) +
cap_num_fault_regs(iommu->cap) * PRIMARY_FAULT_REG_LEN >= PAGE_SIZE ||
ecap_iotlb_offset(iommu->ecap) >= PAGE_SIZE )
break;
case DEV_TYPE_PCIe_ENDPOINT:
- gdprintk(XENLOG_INFO VTDPREFIX,
- "domain_context_mapping:PCIe: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "d%d:PCIe: map bdf = %x:%x.%x\n",
+ domain->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn);
break;
case DEV_TYPE_PCI:
- gdprintk(XENLOG_INFO VTDPREFIX,
- "domain_context_mapping:PCI: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "d%d:PCI: map bdf = %x:%x.%x\n",
+ domain->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn);
if ( ret )
break;
default:
- gdprintk(XENLOG_ERR VTDPREFIX,
- "domain_context_mapping:unknown type : bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): bdf = %x:%x.%x\n",
+ domain->domain_id, type,
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = -EINVAL;
break;
}
+ if ( iommu_verbose )
+ process_pending_softirqs();
+
return ret;
}
goto out;
case DEV_TYPE_PCIe_ENDPOINT:
- gdprintk(XENLOG_INFO VTDPREFIX,
- "domain_context_unmap:PCIe: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "d%d:PCIe: unmap bdf = %x:%x.%x\n",
+ domain->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = domain_context_unmap_one(domain, iommu, bus, devfn);
break;
case DEV_TYPE_PCI:
- gdprintk(XENLOG_INFO VTDPREFIX,
- "domain_context_unmap:PCI: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ if ( iommu_verbose )
+ dprintk(VTDPREFIX, "d%d:PCI: unmap bdf = %x:%x.%x\n",
+ domain->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = domain_context_unmap_one(domain, iommu, bus, devfn);
if ( ret )
break;
break;
default:
- gdprintk(XENLOG_ERR VTDPREFIX,
- "domain_context_unmap:unknown type: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): bdf = %x:%x.%x\n",
+ domain->domain_id, type,
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
ret = -EINVAL;
goto out;
}
ret = domain_context_mapping(pdev->domain, pdev->bus, pdev->devfn);
if ( ret )
{
- gdprintk(XENLOG_ERR VTDPREFIX,
- "intel_iommu_add_device: context mapping failed\n");
+ dprintk(XENLOG_ERR VTDPREFIX, "d%d: context mapping failed\n",
+ pdev->domain->domain_id);
return ret;
}
{
ret = rmrr_identity_mapping(pdev->domain, rmrr);
if ( ret )
- gdprintk(XENLOG_ERR VTDPREFIX,
- "intel_iommu_add_device: RMRR mapping failed\n");
+ dprintk(XENLOG_ERR VTDPREFIX, "d%d: RMRR mapping failed\n",
+ pdev->domain->domain_id);
}
}
if (pdev->domain != dom0)
{
- gdprintk(XENLOG_ERR VTDPREFIX,
+ dprintk(XENLOG_ERR VTDPREFIX,
"IOMMU: assign a assigned device\n");
return -EBUSY;
}
ret = rmrr_identity_mapping(d, rmrr);
if ( ret )
{
- gdprintk(XENLOG_ERR VTDPREFIX,
- "IOMMU: mapping reserved region failed\n");
+ dprintk(XENLOG_ERR VTDPREFIX,
+ "IOMMU: mapping reserved region failed\n");
goto done;
}
}
#include <public/hvm/ioreq.h>
#include <public/domctl.h>
-extern int iommu_enabled;
-extern int iommu_pv_enabled;
-extern int force_iommu;
-extern int iommu_workaround_bios_bug;
-extern int iommu_passthrough;
-extern int iommu_snoop;
-extern int iommu_qinval;
-extern int iommu_intremap;
+extern bool_t iommu_enabled, iommu_pv_enabled;
+extern bool_t force_iommu, iommu_verbose;
+extern bool_t iommu_workaround_bios_bug, iommu_passthrough;
+extern bool_t iommu_snoop, iommu_qinval, iommu_intremap;
#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu)